home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / ada / gwuada_8.zip / DOC.ZIP / WORMS.ADA < prev   
Text File  |  1993-08-18  |  10KB  |  377 lines

  1. --
  2. --    Program : Worms.ada
  3. --    Purpose : This program is based on the UNIX game worms.  It is
  4. --        implemented to show how tasks can be used in ADA.  It
  5. --        is interesting since the Worms program could really be
  6. --        implemented as a sequential program.  This implementation
  7. --        shows how tasks can be used to simplify the design of a
  8. --        sequential program.  By defining the Worms as individual
  9. --        tasks, the programmer only has to worry about defining the
  10. --        behavior of a single Worm, and then creating multiple 
  11. -        instantiations of that Worm.
  12. --
  13. --    To use with GWUMON : To use this program with GWUMON, from the command
  14. --              line type:
  15. --                       adacomp -a -b -mworms worms.ada
  16. --                       gwumon -mworms
  17. --
  18. --    On the intial setup screen, choose 'Y' to the questions if tasks are
  19. --            used.  Also, set the intial speed to 10, the fastest speed 
  20. --        (the monitor will still run slow.  To get a better feel for
  21. --        how the worms run, try running it once not through the
  22. --        monitor).  The first four windows which will show up will be
  23. --        the main procedure WORMS, the task SCREEN, and two instances
  24. --        of the WORM task.  Notice how the WORM task interacts with
  25. --        SCREEN task.  
  26. --        
  27. --    
  28. WITH Text_IO; USE Text_IO;
  29.  
  30. PACKAGE My_Int_IO IS
  31.   NEW Text_IO.Integer_IO (Num => Integer);
  32. --
  33. --  Screen controls the actual printing of the characters to the screen.
  34. --
  35. PACKAGE Screen IS
  36.  
  37.     ScreenDepth: CONSTANT INTEGER := 24;
  38.     ScreenWidth: CONSTANT INTEGER := 80;
  39.  
  40.     SUBTYPE DEPTH IS INTEGER RANGE 1..ScreenDepth;
  41.     SUBTYPE WIDTH is INTEGER RANGE 1..ScreenWidth;
  42.  
  43.     PROCEDURE ClearScreen;
  44.     PROCEDURE MoveCursor(Column : Width; Row : Depth);
  45.     PROCEDURE Beep(HowMany: POSITIVE);
  46. END Screen;
  47.  
  48. --
  49. --  Screen_IO contains the task which controls the concurrency in the
  50. --  I/O to the screen.
  51. --
  52. WITH Screen;
  53. USE Screen;
  54. PACKAGE Screen_IO IS
  55.     
  56.     TASK Terminal IS
  57.         ENTRY WriteAt( Column : Width; Row : Depth; What : Character );
  58.     END Terminal;
  59. END Screen_IO;
  60.  
  61. --::::::::::
  62. --random.ads
  63. --::::::::::
  64. PACKAGE Random IS
  65.  
  66. -- Simple pseudo-random number generator package.
  67. -- Adapated from the Ada literature by
  68. -- Michael B. Feldman, The George Washington University, November 1990.
  69.  
  70.   PROCEDURE Set_Seed (N : Positive);
  71.  
  72.   FUNCTION  Unit_Random RETURN Float;
  73.  
  74.     --returns a float >=0.0 and <1.0
  75.  
  76.   FUNCTION  Random_Int (N : Positive) RETURN Positive;
  77.  
  78.     --return a random integer in the range 1..N
  79.  
  80. END Random;
  81.  
  82. --
  83. -- Creatures is the package in which worms resides.  
  84. --
  85.  
  86. PACKAGE Creatures IS
  87.  
  88.     TASK TYPE Worm IS 
  89.         ENTRY Init_Worm( Symbol : IN CHARACTER  );
  90.     END Worm;
  91.  
  92.     TYPE Coordinate IS
  93.         RECORD
  94.             x,y : Integer;
  95.         END RECORD;
  96.  
  97.     Maximum_xy : Coordinate;
  98.     Minimum_xy : Coordinate;
  99.  
  100. PRIVATE
  101.     Max_Length : CONSTANT INTEGER :=6;
  102.     SUBTYPE Length IS POSITIVE RANGE 1..Max_Length;
  103.     TYPE Worm_Definition IS ARRAY(Length) of Coordinate;
  104.     FUNCTION New_Direction RETURN INTEGER;
  105.     PROCEDURE Move_Worm( Worm_Position : IN OUT Worm_Definition;
  106.                          Symbol : IN CHARACTER );
  107. END Creatures;
  108.  
  109. --
  110. --  Implementation of the Screen Package
  111. --
  112. with TEXT_IO;
  113. with My_Int_IO;
  114.  
  115. PACKAGE BODY Screen is
  116.     
  117.     PROCEDURE Beep(HowMany: POSITIVE) IS
  118.     BEGIN
  119.         FOR count IN 1..HowMany LOOP
  120.             Text_IO.put( Item => ASCII.BEL);
  121.         END LOOP;
  122.     END Beep;
  123.    
  124.     PROCEDURE ClearScreen IS
  125.     BEGIN
  126.         Text_IO.Put(Item => ASCII.ESC);
  127.         Text_IO.Put (Item => "[2J" );
  128.     END ClearScreen;
  129.   
  130.     PROCEDURE MoveCursor(Column : Width; Row : Depth) IS
  131.     BEGIN
  132.         Text_IO.New_Line;
  133.         Text_IO.Put (Item => ASCII.ESC);
  134.         Text_IO.Put ("[");
  135.         My_Int_IO.Put (Item => Row, Width => 1);
  136.         Text_IO.Put (";");
  137.         My_Int_IO.Put (Item => Column, Width => 1);
  138.         Text_IO.Put ("f");
  139.     END MoveCursor;
  140. END Screen;
  141.  
  142.  
  143. --
  144. --  Implementation of the Screen_IO package
  145. --
  146.  
  147. with Text_IO;
  148. with Screen;
  149. use Screen;
  150. PACKAGE BODY Screen_IO IS
  151.  
  152.     TASK BODY Terminal IS
  153.  
  154.     BEGIN
  155.        Screen.ClearScreen;
  156.        LOOP
  157.             SELECT
  158.                 ACCEPT WriteAt(Column : Width; Row : Depth; What : Character) DO
  159.                     Screen.MoveCursor( Column, Row );
  160.                     Text_IO.Put( What );
  161.                 END WriteAt;
  162.             OR
  163.                 TERMINATE;
  164.             END SELECT;
  165.        END LOOP;
  166.     END Terminal;
  167. END Screen_IO;
  168.  
  169. --::::::::::
  170. --random.adb
  171. --::::::::::
  172. WITH Calendar;
  173. USE  Calendar;
  174.  
  175. PACKAGE BODY Random IS
  176.  
  177. -- Body of random number generator package.
  178. -- Adapted from the Ada literature by
  179. -- Michael B. Feldman, The George Washington University, November 1990.
  180.  
  181.   Modulus      : CONSTANT := 9317;
  182.  
  183.   TYPE Int_16 IS RANGE - 2 ** 15 .. 2 ** 15 - 1;
  184.  
  185.   TYPE Int_32 IS RANGE - 2 ** 31 .. 2 ** 31 - 1;
  186.  
  187.   SUBTYPE Seed_Range IS Int_16 RANGE 0 .. (Modulus - 1);
  188.  
  189.   Seed,
  190.   Default_Seed : Seed_Range;
  191.  
  192.   PROCEDURE Set_Seed (N : Positive) IS SEPARATE;
  193.  
  194.   FUNCTION  Unit_Random RETURN Float IS SEPARATE;
  195.  
  196.   FUNCTION  Random_Int (N : Positive) RETURN Positive IS SEPARATE;
  197. BEGIN
  198.   Default_Seed := Int_16 (Int_32 (Seconds (Clock)) MOD Modulus);
  199.   Seed := Default_Seed;
  200. END Random;
  201.  
  202. SEPARATE (Random)
  203.  
  204. PROCEDURE Set_Seed (N : Positive) IS
  205. BEGIN
  206.   Seed := Seed_Range (N);
  207. END Set_Seed;
  208.  
  209. SEPARATE (Random)
  210.  
  211. FUNCTION  Unit_Random RETURN Float IS
  212.   Multiplier : CONSTANT := 421;
  213.   Increment  : CONSTANT := 2073;
  214.   Result     : Float;
  215. BEGIN
  216.   Seed := (Multiplier * Seed + Increment) MOD Modulus;
  217.   Result := Float (Seed) / Float (Modulus);
  218.   RETURN Result;
  219. EXCEPTION
  220.   WHEN Constraint_Error | Numeric_Error =>
  221.     Seed := Int_16 ((Multiplier * Int_32 (Seed) + Increment) MOD Modulus);
  222.     Result := Float (Seed) / Float (Modulus);
  223.     RETURN Result;
  224.  
  225. END Unit_Random;
  226.  
  227. SEPARATE (Random)
  228.  
  229. FUNCTION  Random_Int (N : Positive) RETURN Positive IS
  230.   Result : Integer RANGE 1 .. N;
  231. BEGIN
  232.   Result := Integer (Float (N) * Unit_Random + 0.5);
  233.   RETURN Result;
  234. EXCEPTION
  235.   WHEN Constraint_Error | Numeric_Error =>
  236.     RETURN 1;
  237.  
  238. END Random_Int;
  239.  
  240. --
  241. --  Implementation of the Creature.  In this case, it is a worm.
  242. --
  243.  
  244. WITH Screen; USE Screen;
  245. WITH Screen_IO; USE Screen_IO;
  246. WITH Random; USE Random;
  247. PACKAGE BODY Creatures IS
  248.  
  249. --
  250. --  New_Direction finds the new direction for the worm to move
  251. --
  252.  
  253.     FUNCTION New_Direction RETURN INTEGER IS
  254.         Direction : Integer;
  255.     BEGIN
  256.         Direction := Random.Random_Int(10);
  257.         IF Direction > 5 THEN
  258.             Direction := -1;
  259.     ELSE
  260.         Direction := 1;
  261.         END IF;
  262.         RETURN Direction;
  263.     END New_Direction;
  264.  
  265. --
  266. --  Move_Worm actually moves the worm 
  267. --
  268.  
  269.     PROCEDURE Move_Worm( Worm_Position : IN OUT Worm_Definition;
  270.                          Symbol : IN CHARACTER ) IS
  271.     BEGIN
  272.  
  273.         Terminal.WriteAt( Worm_Position(Max_Length).x, 
  274.                           Worm_Position(Max_Length).y, ' ' );
  275.  
  276.         FOR I in REVERSE 2..Max_Length LOOP
  277.             Worm_Position(I) := Worm_Position(I-1);
  278.             Terminal.WriteAt( Worm_Position(I).x, Worm_Position(I).y, 
  279.                                Symbol );
  280.         END LOOP;
  281.  
  282.         Worm_Position(1).x := Worm_Position(1).x + New_Direction;
  283.         IF Worm_Position(1).x < Minimum_xy.x THEN
  284.             Worm_Position(1).x := Minimum_xy.x;
  285.         END IF;
  286.         IF Worm_Position(1).x > Maximum_xy.x THEN
  287.             Worm_Position(1).x := Maximum_xy.x;
  288.         END IF;
  289.  
  290.         Worm_Position(1).y := Worm_Position(1).y + New_Direction;
  291.         IF Worm_Position(1).y < Minimum_xy.y THEN
  292.             Worm_Position(1).y := Minimum_xy.y;
  293.         END IF;
  294.         IF Worm_Position(1).y > Maximum_xy.y THEN
  295.             Worm_Position(1).y := Maximum_xy.y;
  296.         END IF;
  297.  
  298.         Terminal.WriteAt( Worm_Position(1).x, Worm_Position(1).y, 
  299.                                Symbol );
  300.     END;
  301.  
  302. --
  303. --  This is the body for the worm task.
  304. --
  305.  
  306.     TASK BODY W